using System;
using System.Collections;
using PHSRAG.Insight21.InsightUtilities.Enums;

namespace PHSRAG.Insight21.Humans
{
    /// <summary>
    /// Property  the protocol documents should be sorted by in a collection.
    /// </summary>
    public enum ProtocolDocumentSortByType
    {
        /// <summary>
        /// Sort by Type.
        /// </summary>
        Type,
        /// <summary>
        /// Sort by Name.
        /// </summary>
        Name,
        /// <summary>
        /// Sort by Process Name.
        /// </summary>
        ProcessName,
        /// <summary>
        /// Sort by Date Rceived.
        /// </summary>
        DateReceived
    }

    /// <summary>
    /// Comparer class for sorting ProtocolDocument items in collections.
    /// </summary>
    public class ProtocolDocumentComparer : IComparer
    {
        #region Private Members

        private SortOrder _sortOrder;
        private ProtocolDocumentSortByType _sortByType;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ProtocolDocumentComparer"/> class.
        /// </summary>
        /// <param name="sortOrder">The sort order.</param>
        /// <param name="sortByType">Type of the sort by.</param>
        public ProtocolDocumentComparer(SortOrder sortOrder, ProtocolDocumentSortByType sortByType)
        {
            SortOrder = sortOrder;
            SortByType = sortByType;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the sort order.
        /// </summary>
        /// <value>The sort order.</value>
        public SortOrder SortOrder
        {
            get { return _sortOrder; }
            set { _sortOrder = value; }
        }

        /// <summary>
        /// Gets or sets the property to sort by.
        /// </summary>
        /// <value>The property to sort by.</value>
        public ProtocolDocumentSortByType SortByType
        {
            get { return _sortByType; }
            set { _sortByType = value; }
        }

        #endregion

        #region IComparer Members

        /// <summary>
        /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
        /// </summary>
        /// <param name="x">The first object to compare.</param>
        /// <param name="y">The second object to compare.</param>
        /// <returns>
        /// Value
        /// Condition
        /// Less than zero
        /// <paramref name="x"/> is less than <paramref name="y"/>.
        /// Zero
        /// <paramref name="x"/> equals <paramref name="y"/>.
        /// Greater than zero
        /// <paramref name="x"/> is greater than <paramref name="y"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// Neither <paramref name="x"/> nor <paramref name="y"/> implements the <see cref="T:System.IComparable"/> interface.
        /// -or-
        /// <paramref name="x"/> and <paramref name="y"/> are of different types and neither one can handle comparisons with the other.
        /// </exception>
        public int Compare(object x, object y)
        {
            ProtocolDocument xProtocolDocument = x as ProtocolDocument;
            ProtocolDocument yProtocolDocument = y as ProtocolDocument;

            int sortOrderIndicator = (SortOrder == SortOrder.Asc) ? 1 : -1;

            // Eliminate cases where any of the docs is null
            if ((xProtocolDocument == null) && (yProtocolDocument != null))
            {
                return -1 * sortOrderIndicator;
            }

            if ((xProtocolDocument != null) && (yProtocolDocument == null))
            {
                return 1 * sortOrderIndicator;
            }

            if (xProtocolDocument == null)
            {
                return 0;
            }

            // If none of the docs is null
            switch (SortByType)
            {
                case ProtocolDocumentSortByType.Type:
                    return string.Compare(xProtocolDocument.Type, yProtocolDocument.Type) * sortOrderIndicator;
                case ProtocolDocumentSortByType.Name:
                    return string.Compare(xProtocolDocument.Name, yProtocolDocument.Name) * sortOrderIndicator;
                case ProtocolDocumentSortByType.ProcessName:
                    return string.Compare(xProtocolDocument.ProcessName, yProtocolDocument.ProcessName) * sortOrderIndicator;
                case ProtocolDocumentSortByType.DateReceived:
                    return DateTime.Compare(xProtocolDocument.DateReceived, yProtocolDocument.DateReceived) * sortOrderIndicator;
                default:
                    return DateTime.Compare(xProtocolDocument.DateReceived, yProtocolDocument.DateReceived) * sortOrderIndicator;
            }
        }

        #endregion
    }
}
